/**
 * @file software_upgrade.h
 * @brief 软件升级数据传输模块 - 处理软件升级相关的所有数据类型
 * @details 本模块实现了104协议的软件升级数据处理功能，包括软件升级命令、
 *          软件升级状态、软件升级进度等数据类型的序列化和反序列化操作。
 *          支持完整的数据转换和验证功能。
 * 
 * @author zyb
 * @date 2025-10-17
 * @version 1.0
 * 
 * @note 所有函数都遵循104协议规范，确保严格的数据处理
 * @warning 数据转换失败时应返回相应的错误码，便于上层处理
 * 
 * @see protocol_types.h
 * @see buffer_utils.h
 * @see time_utils.h
 */

#ifndef SOFTWARE_UPGRADE_H
#define SOFTWARE_UPGRADE_H

#include "../../common/types/include/protocol_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/* ==================== 软件升级数据类型定义 ==================== */

/**
 * @brief 软件升级命令类型 (Software Upgrade Command Type)
 */
typedef struct {
    uint8_t se : 1;     /* 选择/执行位 */
    uint8_t res : 7;    /* 预留 */
} software_upgrade_command_type_t;

/**
 * @brief 软件升级命令结构 (F_SR_NA_1)
 */
typedef struct {
    info_addr_t info_address;               /* 信息对象地址 */
    software_upgrade_command_type_t command_type; /* 命令类型 */
} F_SR_NA_1_t;

/**
 * @brief 软件升级状态枚举
 */
typedef enum {
    SOFTWARE_UPGRADE_STATUS_IDLE = 0,        /* 空闲状态 */
    SOFTWARE_UPGRADE_STATUS_STARTING = 1,    /* 启动中 */
    SOFTWARE_UPGRADE_STATUS_TRANSFERRING = 2, /* 传输中 */
    SOFTWARE_UPGRADE_STATUS_INSTALLING = 3,  /* 安装中 */
    SOFTWARE_UPGRADE_STATUS_COMPLETED = 4,   /* 完成 */
    SOFTWARE_UPGRADE_STATUS_FAILED = 5,      /* 失败 */
    SOFTWARE_UPGRADE_STATUS_CANCELLED = 6    /* 取消 */
} software_upgrade_status_t;

/**
 * @brief 软件升级阶段枚举
 */
typedef enum {
    SOFTWARE_UPGRADE_PHASE_START = 0,        /* 启动阶段 */
    SOFTWARE_UPGRADE_PHASE_TRANSFER = 1,    /* 传输阶段 */
    SOFTWARE_UPGRADE_PHASE_INSTALL = 2,     /* 安装阶段 */
    SOFTWARE_UPGRADE_PHASE_COMPLETE = 3,    /* 完成阶段 */
    SOFTWARE_UPGRADE_PHASE_CANCEL = 4       /* 取消阶段 */
} software_upgrade_phase_t;

/**
 * @brief 软件升级状态信息结构
 */
typedef struct {
    info_addr_t info_address;               /* 信息对象地址 */
    software_upgrade_status_t status;       /* 升级状态 */
    software_upgrade_phase_t stage;         /* 升级阶段 */
    u8 progress;                            /* 进度百分比 */
    u16 error_code;                         /* 错误码 */
} software_upgrade_status_info_t;

/**
 * @brief 软件升级进度信息结构
 */
typedef struct {
    info_addr_t info_address;               /* 信息对象地址 */
    u8 progress_percent;                    /* 进度百分比 */
    u32 total_size;                         /* 总大小 */
} software_upgrade_progress_t;

/**
 * @brief 软件版本信息结构
 */
typedef struct {
    char version[32];                       /* 版本号 */
    char build_date[32];                    /* 构建日期 */
    char checksum[64];                      /* 校验和 */
    u32 file_size;                          /* 文件大小 */
    u32 install_size;                       /* 安装大小 */
} software_version_info_t;

/**
 * @brief 软件升级会话结构
 */
typedef struct {
    u32 session_id;                         /* 会话ID */
    software_upgrade_status_t status;       /* 升级状态 */
    software_upgrade_phase_t current_phase;  /* 当前阶段 */
    char target_filename[256];              /* 目标文件名 */
    software_version_info_t current_version; /* 当前版本 */
    software_version_info_t target_version;  /* 目标版本 */
    u32 transferred_size;                   /* 已传输大小 */
    u32 total_size;                         /* 总大小 */
    u8 progress_percentage;                 /* 进度百分比 */
    cp56time2a_t start_time;                /* 开始时间 */
    cp56time2a_t end_time;                  /* 结束时间 */
    char error_message[128];                /* 错误信息 */
} software_upgrade_session_t;

/**
 * @brief 软件升级数据组
 */
typedef struct {
    software_upgrade_session_t* sessions;   /* 升级会话数组 */
    u32 count;                              /* 会话个数 */
    u32 max_count;                          /* 最大会话个数 */
} software_upgrade_data_group_t;

/* ==================== 软件升级命令处理函数 ==================== */

/**
 * @brief 软件升级命令转换为字节数组
 * @details 将软件升级命令结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param command 软件升级命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_software_upgrade_command
 * @see validate_software_upgrade_command
 */
protocol_error_t software_upgrade_command_to_bytes(const F_SR_NA_1_t* command,
                                                 u8* buffer, u32 buffer_size, u32* actual_length);

/**
 * @brief 字节数组转换为软件升级命令
 * @details 将104协议规定的字节数组格式转换为软件升级命令结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param command 软件升级命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳软件升级命令
 * 
 * @see software_upgrade_command_to_bytes
 * @see validate_software_upgrade_command
 */
protocol_error_t bytes_to_software_upgrade_command(const u8* data, u32 length,
                                                  F_SR_NA_1_t* command);

/**
 * @brief 验证软件升级命令
 * @details 验证软件升级命令结构的完整性和有效性。
 *          检查地址和命令类型的有效性。
 * 
 * @param command 软件升级命令结构，不能为NULL
 * @return 验证结果
 *         - 1: 软件升级命令有效
 *         - 0: 软件升级命令无效
 * 
 * @note 验证地址和命令类型的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_software_upgrade_command_type_valid
 * @see F_SR_NA_1_t
 */
int validate_software_upgrade_command(const F_SR_NA_1_t* command);

/* ==================== 软件升级状态处理函数 ==================== */

/**
 * @brief 软件升级状态转换为字节数组
 * @details 将软件升级状态结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param status 软件升级状态结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_software_upgrade_status
 * @see validate_software_upgrade_status
 */
protocol_error_t software_upgrade_status_to_bytes(const software_upgrade_status_info_t* status,
                                                u8* buffer, u32 buffer_size, u32* actual_length);

/**
 * @brief 字节数组转换为软件升级状态
 * @details 将104协议规定的字节数组格式转换为软件升级状态结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param status 软件升级状态结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳软件升级状态
 * 
 * @see software_upgrade_status_to_bytes
 * @see validate_software_upgrade_status
 */
protocol_error_t bytes_to_software_upgrade_status(const u8* data, u32 length,
                                                 software_upgrade_status_info_t* status);

/**
 * @brief 验证软件升级状态
 * @details 验证软件升级状态结构的完整性和有效性。
 *          检查地址、状态、阶段、进度、错误码的有效性。
 * 
 * @param status 软件升级状态结构，不能为NULL
 * @return 验证结果
 *         - 1: 软件升级状态有效
 *         - 0: 软件升级状态无效
 * 
 * @note 验证地址、状态、阶段、进度、错误码的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_software_upgrade_status_valid
 * @see is_software_upgrade_stage_valid
 * @see is_software_upgrade_progress_valid
 * @see is_software_upgrade_error_code_valid
 * @see software_upgrade_status_info_t
 */
int validate_software_upgrade_status(const software_upgrade_status_info_t* status);

/* ==================== 软件升级进度处理函数 ==================== */

/**
 * @brief 软件升级进度转换为字节数组
 * @details 将软件升级进度结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param progress 软件升级进度结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_software_upgrade_progress
 * @see validate_software_upgrade_progress
 */
protocol_error_t software_upgrade_progress_to_bytes(const software_upgrade_progress_t* progress,
                                                  u8* buffer, u32 buffer_size, u32* actual_length);

/**
 * @brief 字节数组转换为软件升级进度
 * @details 将104协议规定的字节数组格式转换为软件升级进度结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param progress 软件升级进度结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_ASDU_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳软件升级进度
 * 
 * @see software_upgrade_progress_to_bytes
 * @see validate_software_upgrade_progress
 */
protocol_error_t bytes_to_software_upgrade_progress(const u8* data, u32 length,
                                                   software_upgrade_progress_t* progress);

/**
 * @brief 验证软件升级进度
 * @details 验证软件升级进度结构的完整性和有效性。
 *          检查地址、进度百分比、总大小、已传输大小的有效性。
 * 
 * @param progress 软件升级进度结构，不能为NULL
 * @return 验证结果
 *         - 1: 软件升级进度有效
 *         - 0: 软件升级进度无效
 * 
 * @note 验证地址、进度百分比、总大小、已传输大小的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_software_upgrade_progress_valid
 * @see is_software_upgrade_file_size_valid
 * @see software_upgrade_progress_t
 */
int validate_software_upgrade_progress(const software_upgrade_progress_t* progress);

/* ==================== 辅助函数 ==================== */

/**
 * @brief 获取软件升级命令大小
 * @details 获取软件升级命令结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 软件升级命令大小（字节）
 * 
 * @note 软件升级命令大小：4字节（地址3字节 + 命令类型1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_software_upgrade_status_size
 * @see get_software_upgrade_progress_size
 * @see F_SR_NA_1_t
 */
u32 get_software_upgrade_command_size(void);

/**
 * @brief 获取软件升级状态大小
 * @details 获取软件升级状态结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 软件升级状态大小（字节）
 * 
 * @note 软件升级状态大小：8字节（地址3字节 + 状态1字节 + 阶段1字节 + 进度1字节 + 错误码2字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_software_upgrade_command_size
 * @see get_software_upgrade_progress_size
 * @see software_upgrade_status_info_t
 */
u32 get_software_upgrade_status_size(void);

/**
 * @brief 获取软件升级进度大小
 * @details 获取软件升级进度结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 软件升级进度大小（字节）
 * 
 * @note 软件升级进度大小：12字节（地址3字节 + 进度1字节 + 总大小4字节 + 已传输大小4字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_software_upgrade_command_size
 * @see get_software_upgrade_status_size
 * @see software_upgrade_progress_t
 */
u32 get_software_upgrade_progress_size(void);

/* ==================== 软件升级状态处理函数 ==================== */

/**
 * @brief 获取软件升级状态名称
 * @details 根据软件升级状态枚举值获取对应的中文名称。
 *          用于调试和日志输出。
 * 
 * @param status 软件升级状态枚举值
 * @return 软件升级状态名称字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效状态返回"未知状态"
 * 
 * @see software_upgrade_status_t
 * @see get_software_upgrade_status_description
 */
const char* get_software_upgrade_status_name(software_upgrade_status_t status);

/**
 * @brief 获取软件升级状态描述
 * @details 根据软件升级状态枚举值获取对应的详细描述。
 *          用于调试和日志输出。
 * 
 * @param status 软件升级状态枚举值
 * @return 软件升级状态描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效状态返回"未知状态"
 * 
 * @see software_upgrade_status_t
 * @see get_software_upgrade_status_name
 */
const char* get_software_upgrade_status_description(software_upgrade_status_t status);

/* ==================== 软件升级阶段处理函数 ==================== */

/**
 * @brief 获取软件升级阶段名称
 * @details 根据软件升级阶段枚举值获取对应的中文名称。
 *          用于调试和日志输出。
 * 
 * @param stage 软件升级阶段枚举值
 * @return 软件升级阶段名称字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效阶段返回"未知阶段"
 * 
 * @see software_upgrade_phase_t
 * @see get_software_upgrade_stage_description
 */
const char* get_software_upgrade_stage_name(software_upgrade_phase_t stage);

/**
 * @brief 获取软件升级阶段描述
 * @details 根据软件升级阶段枚举值获取对应的详细描述。
 *          用于调试和日志输出。
 * 
 * @param stage 软件升级阶段枚举值
 * @return 软件升级阶段描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效阶段返回"未知阶段"
 * 
 * @see software_upgrade_phase_t
 * @see get_software_upgrade_stage_name
 */
const char* get_software_upgrade_stage_description(software_upgrade_phase_t stage);

/* ==================== 软件升级验证函数 ==================== */

/**
 * @brief 验证软件升级命令类型
 * @details 验证软件升级命令类型是否在有效范围内。
 *          检查保留位是否都为0。
 * 
 * @param command_type 软件升级命令类型
 * @return 验证结果
 *         - 1: 软件升级命令类型有效
 *         - 0: 软件升级命令类型无效
 * 
 * @note 软件升级命令类型只有1位有效，其他位必须为0
 * @warning 保留位必须为0
 * 
 * @see is_software_upgrade_status_valid
 * @see is_software_upgrade_stage_valid
 * @see software_upgrade_command_type_t
 */
int is_software_upgrade_command_type_valid(const software_upgrade_command_type_t* command_type);

/**
 * @brief 验证软件升级状态
 * @details 验证软件升级状态是否在有效范围内。
 *          软件升级状态范围：0-6
 * 
 * @param status 软件升级状态
 * @return 验证结果
 *         - 1: 软件升级状态有效
 *         - 0: 软件升级状态无效
 * 
 * @note 软件升级状态范围：0-6
 * @warning 软件升级状态不能为负数
 * 
 * @see is_software_upgrade_command_type_valid
 * @see is_software_upgrade_stage_valid
 * @see software_upgrade_status_t
 */
int is_software_upgrade_status_valid(software_upgrade_status_t status);

/**
 * @brief 验证软件升级阶段
 * @details 验证软件升级阶段是否在有效范围内。
 *          软件升级阶段范围：0-4
 * 
 * @param stage 软件升级阶段
 * @return 验证结果
 *         - 1: 软件升级阶段有效
 *         - 0: 软件升级阶段无效
 * 
 * @note 软件升级阶段范围：0-4
 * @warning 软件升级阶段不能为负数
 * 
 * @see is_software_upgrade_status_valid
 * @see is_software_upgrade_command_type_valid
 * @see software_upgrade_phase_t
 */
int is_software_upgrade_stage_valid(software_upgrade_phase_t stage);

/**
 * @brief 验证软件升级进度
 * @details 验证软件升级进度是否在有效范围内。
 *          软件升级进度范围：0-100
 * 
 * @param progress 软件升级进度
 * @return 验证结果
 *         - 1: 软件升级进度有效
 *         - 0: 软件升级进度无效
 * 
 * @note 软件升级进度范围：0-100
 * @warning 软件升级进度不能为负数或超过100
 * 
 * @see is_software_upgrade_file_size_valid
 * @see is_software_upgrade_error_code_valid
 */
int is_software_upgrade_progress_valid(u8 progress);

/**
 * @brief 验证软件升级文件大小
 * @details 验证软件升级文件大小是否在有效范围内。
 *          软件升级文件大小范围：0-4294967295
 * 
 * @param file_size 软件升级文件大小
 * @return 验证结果
 *         - 1: 软件升级文件大小有效
 *         - 0: 软件升级文件大小无效
 * 
 * @note 软件升级文件大小范围：0-4294967295
 * @warning 软件升级文件大小不能为负数
 * 
 * @see is_software_upgrade_progress_valid
 * @see is_software_upgrade_error_code_valid
 */
int is_software_upgrade_file_size_valid(u32 file_size);

/**
 * @brief 验证软件升级错误码
 * @details 验证软件升级错误码是否在有效范围内。
 *          软件升级错误码范围：0-65535
 * 
 * @param error_code 软件升级错误码
 * @return 验证结果
 *         - 1: 软件升级错误码有效
 *         - 0: 软件升级错误码无效
 * 
 * @note 软件升级错误码范围：0-65535
 * @warning 软件升级错误码不能为负数
 * 
 * @see is_software_upgrade_progress_valid
 * @see is_software_upgrade_file_size_valid
 */
int is_software_upgrade_error_code_valid(u16 error_code);

#ifdef __cplusplus
}
#endif

#endif /* SOFTWARE_UPGRADE_H */
